package com.seventeen.monster.redisson.autoconfigure;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.ClusterServersConfig;
import org.redisson.config.Config;
import org.redisson.config.SentinelServersConfig;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * @author seventeen
 */
@Configuration
@EnableConfigurationProperties(RedissonProperties.class)
@ConditionalOnClass({RedissonClient.class})
@ConditionalOnProperty(prefix = "monster.redisson", value = "enable", matchIfMissing = false)
@Import({ListenerContainerConfiguration.class,
        DelayedQueueListenerConfiguration.class, DistributeLockConfiguration.class})
public class RedissonAutoConfiguration {
    public static final String ADDR_SPLIT = ",";

    @Bean
    @ConditionalOnMissingBean(RedissonClient.class)
    @ConditionalOnProperty(prefix = "monster.redisson.single", value = {"address"})
    public RedissonClient singleRedissonClient(RedissonProperties redissonProperties) {
        RedissonProperties.Single single = redissonProperties.getSingle();
        String password = single.getPassword();
        String address = single.getAddress();
        Config config = new Config();
        config.useSingleServer()
                .setAddress("redis://" + address);
        if (password != null) {
            config.useSingleServer()
                    .setPassword(password);
        }
        return Redisson.create(config);
    }

    @Bean
    @ConditionalOnMissingBean(RedissonClient.class)
    @ConditionalOnProperty(prefix = "monster.redisson.sentinel", value = {"address"})
    public RedissonClient sentinelRedissonClient(RedissonProperties redissonProperties) {
        RedissonProperties.Sentinel sentinel = redissonProperties.getSentinel();
        String masterName = sentinel.getMasterName();
        Config config = new Config();
        SentinelServersConfig sentinelServersConfig = config.useSentinelServers()
                .setMasterName(masterName);
        String password = sentinel.getPassword();
        if (password != null) {
            sentinelServersConfig.setPassword(password);
        }
        String sentinelAddress = sentinel.getSentinelAddress();
        for (String address : sentinelAddress.split(ADDR_SPLIT)) {
            sentinelServersConfig.addSentinelAddress("redis://" + address);
        }
        return Redisson.create(config);
    }

    @Bean
    @ConditionalOnMissingBean(RedissonClient.class)
    @ConditionalOnProperty(prefix = "monster.redisson.cluster", value = {"address"})
    public RedissonClient clusterRedissonClient(RedissonProperties redissonProperties) {
        RedissonProperties.Cluster cluster = redissonProperties.getCluster();
        Config config = new Config();
        ClusterServersConfig clusterServersConfig = config.useClusterServers();
        String password = cluster.getPassword();
        if (password != null) {
            clusterServersConfig.setPassword(password);
        }
        String nodeAddress = cluster.getNodeAddress();
        for (String address : nodeAddress.split(ADDR_SPLIT)) {
            clusterServersConfig.addNodeAddress("redis://" + address);
        }
        return Redisson.create(config);
    }
}